/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */

#include "common/lang/comparator.h"
#include "common/lang/sstream.h"
#include "common/log/log.h"
#include "common/type/date_type.h"
#include "common/value.h"
bool check_date_format(const string &data)
{
  // 检查基本格式：至少有一个数字-数字-数字的结构
    size_t first_dash = data.find('-');
    size_t second_dash = data.find('-', first_dash + 1);
    
    if (first_dash == string::npos || second_dash == string::npos ||
        first_dash == 0 || second_dash == first_dash + 1 ||
        second_dash == data.length() - 1) {
        return false;
    }
    
    // 检查各部分是否都是数字
    for (size_t i = 0; i < data.length(); ++i) {
        if (i != first_dash && i != second_dash && !isdigit(data[i])) {
            return false;
        }
    }
    
    // 解析年、月、日
    int year, month, day;
    istringstream iss(data);
    char dash1, dash2;
    
    if (!(iss >> year >> dash1 >> month >> dash2 >> day) || 
        dash1 != '-' || dash2 != '-') {
        return false;
    }
    
    // 检查月份和日期的有效性
    if (month < 1 || month > 12 || day < 1 || day > 31) {
        return false;
    }
    
    if (month == 2) {
        // 检查闰年
        if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
            // 闰年，2月有29天
            if (day > 29) {
                return false;
            }
        } else {
            // 平年，2月有28天
            if (day > 28) {
                return false;
            }
        }
    } else if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) {
        // 4月、6月、9月、11月只有30天
        return false;
    }
    
    return true;
}

int DateType::compare(const Value &left, const Value &right) const
{
  // ASSERT(left.attr_type() == AttrType::DATES, "left type is not date");
  // ASSERT(right.attr_type() == AttrType::DATES, "right type is not date");
  if (right.attr_type() == AttrType::NULLS) {
    return left.attr_type() == AttrType::NULLS ? 0 : 1; // NULL < any non-NULL
  }
  if(left.attr_type() != AttrType::DATES || right.attr_type() != AttrType::DATES) {
    LOG_WARN("compare error, left type: %d, right type: %d", (int)left.attr_type(), (int)right.attr_type());
    return INT32_MAX;
  }
  return common::compare_int((void *)&left.value_.int_value_, (void *)&right.value_.int_value_);
}
RC DateType::add(const Value &left, const Value &right, Value &result) const
{

  //   if (right.attr_type() == AttrType::INTS) {
  //     return common::compare_int((void *)&left.value_.int_value_, (void *)&right.value_.int_value_);
  //   } else if (right.attr_type() == AttrType::FLOATS) {
  //     float left_val  = left.get_float();
  //     float right_val = right.get_float();
  //     return common::compare_float((void *)&left_val, (void *)&right_val);
  //   }
  return RC::UNSUPPORTED;
}

RC DateType::cast_to(const Value &val, AttrType type, Value &result) const
{
  //   switch (type) {
  //     case AttrType::FLOATS: {
  //       float float_value = val.get_int();
  //       result.set_float(float_value);
  //       return RC::SUCCESS;
  //     }
  //     default: LOG_WARN("unsupported type %d", type); return RC::SCHEMA_FIELD_TYPE_MISMATCH;
  //   }
  return RC::UNSUPPORTED;
}

RC DateType::subtract(const Value &left, const Value &right, Value &result) const { return RC::UNSUPPORTED; }

RC DateType::multiply(const Value &left, const Value &right, Value &result) const { return RC::UNSUPPORTED; }

RC   DateType::negative(const Value &val, Value &result) const { return RC::UNSUPPORTED; }

RC DateType::set_value_from_str(Value &val, const string &data) const
{
  RC  rc = RC::SUCCESS;
    if (!check_date_format(data)) {
        LOG_WARN("invalid date format: %s", data.c_str());
        return RC::SCHEMA_FIELD_TYPE_MISMATCH;
    }
 
  val.set_date(data.c_str(), data.length());

  return rc;
}
RC DateType::MaxValue(Value &result) const
{
  // 设置 result 为一个非常大的日期值，例如 9999-12-31


  result.set_int(INT32_MAX); // 假设日期格式为 YYYYMMDD
  result.set_type(AttrType::DATES);
  return RC::SUCCESS;
}
RC DateType::MinValue(Value &result) const
{
  // 设置 result 为一个非常小的日期值，例如 0000-01-01
  result.set_int(INT32_MIN); // 假设日期格式为 YYYYMMDD
  result.set_type(AttrType::DATES);
  return RC::SUCCESS;
}

RC DateType::to_string(const Value &val, string &result) const
{
  stringstream ss;
  string year = std::to_string(val.value_.int_value_/10000);
  string month = std::to_string((val.value_.int_value_/100)%100);
  string day = std::to_string(val.value_.int_value_%100);
  if (month.length() == 1) {
    month = "0" + month; // 前导0
  }
  if (day.length() == 1) {
    day = "0" + day; // 前导0
  }
  ss << year << "-" << month << "-" << day;
  result = ss.str();
  return RC::SUCCESS;
}